/// FTP命令枚举
#[derive(Debug, Clone)]
pub enum FtpCommand {
    // 认证命令
    User(String),
    Pass(String),
    Quit,
    Rein,
    
    // 文件操作命令
    List(Option<String>),
    Nlst(Option<String>),
    Retr(String),
    Stor(String),
    Appe(String),
    Dele(String),
    Rnfr(String),
    Rnto(String),
    Size(String),
    Mdtm(String),
    Rest(u64),
    
    // 目录操作命令
    Cwd(String),
    Cdup,
    Pwd,
    Mkd(String),
    Rmd(String),
    
    // 传输模式命令
    Pasv,
    Port(String),
    Type(String),
    Mode(String),
    Stru(String),
    
    // 其他命令
    Syst,
    Feat,
    Help(Option<String>),
    Noop,
    Stat(Option<String>),
    
    // 扩展加密命令
    Auth(String),
    Keyx(String),
    Prot(String),
}

impl FtpCommand {
    pub fn from_string(input: &str) -> Option<Self> {
        let parts: Vec<&str> = input.trim().split_whitespace().collect();
        if parts.is_empty() {
            return None;
        }
        
        let command = parts[0].to_uppercase();
        let args = &parts[1..];
        
        match command.as_str() {
            "USER" => args.first().map(|s| Self::User(s.to_string())),
            "PASS" => args.first().map(|s| Self::Pass(s.to_string())),
            "QUIT" => Some(Self::Quit),
            "REIN" => Some(Self::Rein),
            "LIST" => Some(Self::List(args.first().map(|s| s.to_string()))),
            "NLST" => Some(Self::Nlst(args.first().map(|s| s.to_string()))),
            "RETR" => args.first().map(|s| Self::Retr(s.to_string())),
            "STOR" => args.first().map(|s| Self::Stor(s.to_string())),
            "APPE" => args.first().map(|s| Self::Appe(s.to_string())),
            "DELE" => args.first().map(|s| Self::Dele(s.to_string())),
            "RNFR" => args.first().map(|s| Self::Rnfr(s.to_string())),
            "RNTO" => args.first().map(|s| Self::Rnto(s.to_string())),
            "SIZE" => args.first().map(|s| Self::Size(s.to_string())),
            "MDTM" => args.first().map(|s| Self::Mdtm(s.to_string())),
            "REST" => args.first().and_then(|s| s.parse().ok()).map(Self::Rest),
            "CWD" => args.first().map(|s| Self::Cwd(s.to_string())),
            "CDUP" => Some(Self::Cdup),
            "PWD" => Some(Self::Pwd),
            "MKD" => args.first().map(|s| Self::Mkd(s.to_string())),
            "RMD" => args.first().map(|s| Self::Rmd(s.to_string())),
            "PASV" => Some(Self::Pasv),
            "PORT" => args.first().map(|s| Self::Port(s.to_string())),
            "TYPE" => args.first().map(|s| Self::Type(s.to_string())),
            "MODE" => args.first().map(|s| Self::Mode(s.to_string())),
            "STRU" => args.first().map(|s| Self::Stru(s.to_string())),
            "SYST" => Some(Self::Syst),
            "FEAT" => Some(Self::Feat),
            "HELP" => Some(Self::Help(args.first().map(|s| s.to_string()))),
            "NOOP" => Some(Self::Noop),
            "STAT" => Some(Self::Stat(args.first().map(|s| s.to_string()))),
            "AUTH" => args.first().map(|s| Self::Auth(s.to_string())),
            "KEYX" => args.first().map(|s| Self::Keyx(s.to_string())),
            "PROT" => args.first().map(|s| Self::Prot(s.to_string())),
            _ => None,
        }
    }
    
    pub fn to_string(&self) -> String {
        match self {
            Self::User(username) => format!("USER {}", username),
            Self::Pass(password) => format!("PASS {}", password),
            Self::Quit => "QUIT".to_string(),
            Self::Rein => "REIN".to_string(),
            Self::List(path) => match path {
                Some(p) => format!("LIST {}", p),
                None => "LIST".to_string(),
            },
            Self::Nlst(path) => match path {
                Some(p) => format!("NLST {}", p),
                None => "NLST".to_string(),
            },
            Self::Retr(filename) => format!("RETR {}", filename),
            Self::Stor(filename) => format!("STOR {}", filename),
            Self::Appe(filename) => format!("APPE {}", filename),
            Self::Dele(filename) => format!("DELE {}", filename),
            Self::Rnfr(filename) => format!("RNFR {}", filename),
            Self::Rnto(filename) => format!("RNTO {}", filename),
            Self::Size(filename) => format!("SIZE {}", filename),
            Self::Mdtm(filename) => format!("MDTM {}", filename),
            Self::Rest(offset) => format!("REST {}", offset),
            Self::Cwd(path) => format!("CWD {}", path),
            Self::Cdup => "CDUP".to_string(),
            Self::Pwd => "PWD".to_string(),
            Self::Mkd(path) => format!("MKD {}", path),
            Self::Rmd(path) => format!("RMD {}", path),
            Self::Pasv => "PASV".to_string(),
            Self::Port(addr) => format!("PORT {}", addr),
            Self::Type(mode) => format!("TYPE {}", mode),
            Self::Mode(mode) => format!("MODE {}", mode),
            Self::Stru(mode) => format!("STRU {}", mode),
            Self::Syst => "SYST".to_string(),
            Self::Feat => "FEAT".to_string(),
            Self::Help(topic) => match topic {
                Some(t) => format!("HELP {}", t),
                None => "HELP".to_string(),
            },
            Self::Noop => "NOOP".to_string(),
            Self::Stat(path) => match path {
                Some(p) => format!("STAT {}", p),
                None => "STAT".to_string(),
            },
            Self::Auth(plugin) => format!("AUTH {}", plugin),
            Self::Keyx(key) => format!("KEYX {}", key),
            Self::Prot(level) => format!("PROT {}", level),
        }
    }
}
